package com.medical.service.impl;

import com.medical.common.PageResult;
import com.medical.entity.Appointment;
import com.medical.repository.AppointmentRepository;
import com.medical.service.AppointmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 专家门诊预约服务实现类
 */
@Service
@Transactional
public class AppointmentServiceImpl implements AppointmentService {
    
    @Autowired
    private AppointmentRepository appointmentRepository;
    
    // 时间段配置
    private static final String[] TIME_SLOTS = {
        "08:00-09:00", "09:00-10:00", "10:00-11:00", "11:00-12:00",
        "14:00-15:00", "15:00-16:00", "16:00-17:00", "17:00-18:00"
    };
    
    @Override
    public Appointment createAppointment(Appointment appointment) {
        // 生成预约单号
        appointment.setAppointmentNo("APT" + System.currentTimeMillis());
        appointment.setStatus("PENDING");
        appointment.setCreateTime(LocalDateTime.now());
        appointment.setUpdateTime(LocalDateTime.now());
        
        return appointmentRepository.save(appointment);
    }
    
    @Override
    public Appointment updateAppointmentStatus(Long appointmentId, String status) {
        Appointment appointment = appointmentRepository.findById(appointmentId)
            .orElseThrow(() -> new RuntimeException("预约记录不存在"));
        
        appointment.setStatus(status);
        appointment.setUpdateTime(LocalDateTime.now());
        
        return appointmentRepository.save(appointment);
    }
    
    @Override
    public Appointment getAppointmentById(Long id) {
        return appointmentRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("预约记录不存在"));
    }
    
    @Override
    public Appointment getAppointmentByNo(String appointmentNo) {
        return appointmentRepository.findByAppointmentNo(appointmentNo);
    }
    
    @Override
    public PageResult<Appointment> getAppointments(int page, int size, Long patientId, Long doctorId, String status) {
        Pageable pageable = PageRequest.of(page - 1, size);
        Page<Appointment> appointmentPage;
        
        if (patientId != null) {
            appointmentPage = appointmentRepository.findByPatientIdOrderByCreateTimeDesc(patientId, pageable);
        } else if (doctorId != null) {
            appointmentPage = appointmentRepository.findByDoctorIdOrderByCreateTimeDesc(doctorId, pageable);
        } else if (status != null) {
            appointmentPage = appointmentRepository.findByStatusOrderByCreateTimeDesc(status, pageable);
        } else {
            appointmentPage = appointmentRepository.findAll(pageable);
        }
        
        return PageResult.of(appointmentPage.getTotalElements(), appointmentPage.getContent());
    }
    
    @Override
    public List<Appointment> getPatientAppointments(Long patientId) {
        return appointmentRepository.findByPatientIdOrderByCreateTimeDesc(patientId);
    }
    
    @Override
    public List<Appointment> getDoctorAppointments(Long doctorId) {
        return appointmentRepository.findByDoctorIdOrderByCreateTimeDesc(doctorId);
    }
    
    @Override
    public List<Appointment> getAppointmentsByDate(LocalDate date, Long doctorId) {
        return appointmentRepository.findByAppointmentDateAndDoctorId(date, doctorId);
    }
    
    @Override
    public Appointment cancelAppointment(Long appointmentId, String reason) {
        Appointment appointment = getAppointmentById(appointmentId);
        
        if (!"PENDING".equals(appointment.getStatus()) && !"APPROVED".equals(appointment.getStatus())) {
            throw new RuntimeException("只有待审核或已批准的预约才能取消");
        }
        
        appointment.setStatus("CANCELLED");
        appointment.setRemark(appointment.getRemark() + "\n取消原因：" + reason);
        appointment.setUpdateTime(LocalDateTime.now());
        
        return appointmentRepository.save(appointment);
    }
    
    @Override
    public boolean checkAppointmentConflict(LocalDate date, String timeSlot, Long doctorId) {
        Long count = appointmentRepository.countByDateAndTimeSlotAndDoctor(date, timeSlot, doctorId);
        return count > 0;
    }
    
    @Override
    public List<String> getAvailableTimeSlots(LocalDate date, Long doctorId) {
        List<String> availableSlots = new ArrayList<>();
        
        for (String timeSlot : TIME_SLOTS) {
            if (!checkAppointmentConflict(date, timeSlot, doctorId)) {
                availableSlots.add(timeSlot);
            }
        }
        
        return availableSlots;
    }
}
